<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Add an atmospheric sky layer to a map</title>
    <meta
      name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no"
    />
    <script src="../../lib/mapbox-gl.js"></script>
    <link href="../../lib/mapbox-gl.css" rel="stylesheet" />
    <script src="../../lib/axios.min.js"></script>
    <script src="../../lib/suncalc.min.js"></script>
    <style>
      body {
        margin: 0;
        padding: 0;
      }
      #map {
        position: absolute;
        top: 0;
        bottom: 0;
        width: 100%;
      }
      .boxdraw {
        background: rgba(56, 135, 190, 0.1);
        border: 2px solid #3887be;
        position: absolute;
        top: 0;
        left: 0;
        width: 0;
        height: 0;
      }
    </style>
  </head>
  <body>
    <div id="map"></div>
    <script>
      let baseDataUrl = `http://${localStorage.getItem(
        "host"
      )}/mapbox-gl-js-offline-examples`;
      axios
        .get(
          baseDataUrl +
            `/resources/styles/${localStorage.getItem(
              "mbtilesStylesName"
            )}.json`
        )
        .then((res) => {
          let data = res.data;
          initMap(data);
        })
        .catch((err) => {
          console.error(err);
        });

      function initMap(style) {
        let map = new mapboxgl.Map({
          container: "map",
          center: [-98, 38.88],
          minZoom: 2,
          zoom: 3,
          style: style,
        });

        // Disable default box zooming.
        map.boxZoom.disable();

        // Create a popup, but don't add it to the map yet.
        var popup = new mapboxgl.Popup({
          closeButton: false,
        });

        map.on("load", function () {
          var canvas = map.getCanvasContainer();

          // Variable to hold the starting xy coordinates
          // when `mousedown` occured.
          var start;

          // Variable to hold the current xy coordinates
          // when `mousemove` or `mouseup` occurs.
          var current;

          // Variable for the draw box element.
          var box;

          // Add the source to query. In this example we're using
          // county polygons uploaded as vector tiles
          map.addLayer(
            {
              id: "counties",
              type: "fill",
              source: "counties",
              "source-layer": "original",
              paint: {
                "fill-outline-color": "rgba(0,0,0,0.1)",
                "fill-color": "rgba(0,0,0,0.1)",
              },
            },
            "settlement-label"
          ); // Place polygon under these labels.

          map.addLayer(
            {
              id: "counties-highlighted",
              type: "fill",
              source: "counties",
              "source-layer": "original",
              paint: {
                "fill-outline-color": "#484896",
                "fill-color": "#6e599f",
                "fill-opacity": 0.75,
              },
              filter: ["in", "FIPS", ""],
            },
            "settlement-label"
          ); // Place polygon under these labels.

          // Set `true` to dispatch the event before other functions
          // call it. This is necessary for disabling the default map
          // dragging behaviour.
          canvas.addEventListener("mousedown", mouseDown, true);

          // Return the xy coordinates of the mouse position
          function mousePos(e) {
            var rect = canvas.getBoundingClientRect();
            return new mapboxgl.Point(
              e.clientX - rect.left - canvas.clientLeft,
              e.clientY - rect.top - canvas.clientTop
            );
          }

          function mouseDown(e) {
            // Continue the rest of the function if the shiftkey is pressed.
            if (!(e.shiftKey && e.button === 0)) return;

            // Disable default drag zooming when the shift key is held down.
            map.dragPan.disable();

            // Call functions for the following events
            document.addEventListener("mousemove", onMouseMove);
            document.addEventListener("mouseup", onMouseUp);
            document.addEventListener("keydown", onKeyDown);

            // Capture the first xy coordinates
            start = mousePos(e);
          }

          function onMouseMove(e) {
            // Capture the ongoing xy coordinates
            current = mousePos(e);

            // Append the box element if it doesnt exist
            if (!box) {
              box = document.createElement("div");
              box.classList.add("boxdraw");
              canvas.appendChild(box);
            }

            var minX = Math.min(start.x, current.x),
              maxX = Math.max(start.x, current.x),
              minY = Math.min(start.y, current.y),
              maxY = Math.max(start.y, current.y);

            // Adjust width and xy position of the box element ongoing
            var pos = "translate(" + minX + "px," + minY + "px)";
            box.style.transform = pos;
            box.style.WebkitTransform = pos;
            box.style.width = maxX - minX + "px";
            box.style.height = maxY - minY + "px";
          }

          function onMouseUp(e) {
            // Capture xy coordinates
            finish([start, mousePos(e)]);
          }

          function onKeyDown(e) {
            // If the ESC key is pressed
            if (e.keyCode === 27) finish();
          }

          function finish(bbox) {
            // Remove these events now that finish has been called.
            document.removeEventListener("mousemove", onMouseMove);
            document.removeEventListener("keydown", onKeyDown);
            document.removeEventListener("mouseup", onMouseUp);

            if (box) {
              box.parentNode.removeChild(box);
              box = null;
            }

            // If bbox exists. use this value as the argument for `queryRenderedFeatures`
            if (bbox) {
              var features = map.queryRenderedFeatures(bbox, {
                layers: ["counties"],
              });

              if (features.length >= 1000) {
                return window.alert("Select a smaller number of features");
              }

              // Run through the selected features and set a filter
              // to match features with unique FIPS codes to activate
              // the `counties-highlighted` layer.
              var filter = features.reduce(
                function (memo, feature) {
                  memo.push(feature.properties.FIPS);
                  return memo;
                },
                ["in", "FIPS"]
              );

              map.setFilter("counties-highlighted", filter);
            }

            map.dragPan.enable();
          }

          map.on("mousemove", function (e) {
            var features = map.queryRenderedFeatures(e.point, {
              layers: ["counties-highlighted"],
            });
            // Change the cursor style as a UI indicator.
            map.getCanvas().style.cursor = features.length ? "pointer" : "";

            if (!features.length) {
              popup.remove();
              return;
            }

            var feature = features[0];

            popup
              .setLngLat(e.lngLat)
              .setText(feature.properties.COUNTY)
              .addTo(map);
          });
        });
      }
    </script>
  </body>
</html>
